package com.epam.employeebase.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public final class PagingSupportTag extends SimpleTagSupport{
	private static final String LINK_TEMPLATE = "<a href=\"%s&page=%d\"> %s </a>";
	private static final String PREVIOUS_PAGE_SYMBOL = "<";
	private static final String NEXT_PAGE_SYMBOL = ">";
	private int entriesPerPage;
	private int pagesRange;
	private int currentPageNumber;
	private int entriesNumber;
	private String pageAction;
	private String changeEntriesAction;
	@Override
	public void doTag() throws JspException, IOException {
		
		int halfPagesRange = pagesRange / 2;
		int pagesNumber = entriesNumber / entriesPerPage;
		if( (entriesNumber % entriesPerPage) != 0){
			pagesNumber++;			
		}
		boolean hasNextPage =  (currentPageNumber < pagesNumber) ? true : false;
		boolean hasPrevPage = (currentPageNumber > 1) ? true : false;
		int startPageNumber;
		int endPageNumber;
		if(pagesNumber < pagesRange) {
			startPageNumber = 1;
			endPageNumber = pagesNumber;
		} else if(currentPageNumber - halfPagesRange <= 0){
			startPageNumber = 1;
			endPageNumber = pagesRange;
		} else if(currentPageNumber + halfPagesRange > pagesNumber){
			endPageNumber = pagesNumber;
			startPageNumber = pagesNumber - pagesRange + 1;
		} else {
			startPageNumber = currentPageNumber - halfPagesRange;
			endPageNumber = currentPageNumber + halfPagesRange;
		}
		
		JspWriter writer = getJspContext().getOut();
		StringBuilder content = new StringBuilder();
		content.append("<script type='text/javascript'>");
		content.append("function validateEntriesPerPage(form) {");
		content.append("var regExp = /^[0-9]+$/;");
		content.append("var text = form.entriesTextbox;");
		content.append("if (!regExp.test(text.value)) {");
		content.append("alert('Field should contain only digits.');");
		content.append("return false;");
		content.append("} else if (text.value < 1) {");
		content.append("alert('At least 1 entry per page required.'); ");
		content.append("return false;");
		content.append("} else if (text.value > 200) {");
		content.append("alert('Maximum 200 entries per page available.');");
		content.append("return false;}");
		content.append("return true;}");
		
		content.append("function validatePage(form) {");
		content.append("var regExp = /^[0-9]+$/;");
		content.append("var text = form.goToPage;");
		content.append("if (!regExp.test(text.value)) {");
		content.append("alert('Field should contain only digits.');");
		content.append("return false; ");
		content.append("} else if ( (text.value < 1) || (text.value >");
		content.append(pagesNumber);
		content.append(")) { alert('Value should be between 1 and ");
		content.append(pagesNumber);
		content.append("');");
		content.append("return false;}");
		content.append("return true;}");
		content.append("</script>");	
		
		content.append("<div class='pagingContainer' style='margin-left: auto; margin-right: auto;'>");
		content.append("<div style='float: left;'>");
		
		content.append("<form method='POST' action='");
		content.append(changeEntriesAction);
		content.append("' onsubmit='return validateEntriesPerPage(this);'>");
		content.append("<input type='hidden' name='page' value='1'/>");
		content.append("<label for='entriesTextbox'>Entries per page</label>");
		content.append("<input type='text' id='entriesTextbox' name='entriesPerPage' value='");
		content.append(entriesPerPage);
		content.append("'/>");
		content.append("<input type='submit' value='Change' />");
		content.append("</form>");
		
		content.append("</div>");
		
		content.append("<div style='float:left; margin-left: 150px; margin-right: 150px; text-align: center;'>");		

		if(hasPrevPage){
			content.append(createPageLink(currentPageNumber - 1, PREVIOUS_PAGE_SYMBOL));
		}	
		
		for(int i = startPageNumber; i < currentPageNumber; i++){
			content.append(createPageLink(i, String.valueOf(i)));
		}
		
		content.append(currentPageNumber);
		
		for(int i = currentPageNumber + 1; i <= endPageNumber; i++){
			content.append(createPageLink(i, String.valueOf(i)));
		}
		
		if(hasNextPage){
			content.append(createPageLink(currentPageNumber + 1, NEXT_PAGE_SYMBOL));
		}
		
		content.append("</div>");
		content.append("<div style='float: right;'>");
		content.append("<form method='POST' action='");
		content.append(pageAction);
		content.append("' onsubmit='return validatePage(this);'>");
		content.append("<label for='goToPage'>Page</label>");
		content.append("<input type='text' id='goToPage' name='page'/>"	);
		content.append("<input type='submit' value='Go'/>");
		content.append("</form>");
		content.append("</div>");
		content.append("</div>");
		
		writer.write(content.toString());
	}
	public static Page getPage(int pageNumber, int entriesPerPage){
		int firstEntry = (pageNumber-1)*entriesPerPage;
		return new Page(firstEntry, entriesPerPage);
	}
	private String createPageLink(int pageNumber, String value){
		return String.format(LINK_TEMPLATE, pageAction, pageNumber, value);		
	}
	
	public int getEntriesPerPage() {
		return entriesPerPage;
	}
	public void setEntriesPerPage(int entriesPerPage) {
		this.entriesPerPage = entriesPerPage;
	}
	public int getCurrentPageNumber() {
		return currentPageNumber;
	}
	public void setCurrentPageNumber(int currentPageNumber) {
		this.currentPageNumber = currentPageNumber;
	}
	public int getPagesRange() {
		return pagesRange;
	}
	public void setPagesRange(int pagesRange) {
		this.pagesRange = pagesRange;
	}
	public String getPageAction() {
		return pageAction;
	}
	public void setPageAction(String pageAction) {
		this.pageAction = pageAction;
	}
	public int getEntriesNumber() {
		return entriesNumber;
	}
	public void setEntriesNumber(int entriesNumber) {
		this.entriesNumber = entriesNumber;
	}
	public String getChangeEntriesAction() {
		return changeEntriesAction;
	}
	public void setChangeEntriesAction(String changeEntriesAction) {
		this.changeEntriesAction = changeEntriesAction;
	}
	
}
